package GameServer

import (
	"PBMessage"
	. "SGNet"
	proto "github.com/golang/protobuf/proto"
	log "misc/seelog"
	"strconv"
	"time"
	cfg "utils/config"
)

const (
	HALLTICK_TIME = 1000 //毫秒单位
)

type GameHall struct {
	ModuleInfo
	clients            map[string]*ClientPlayer
	hallTickTime       int
	ServerClientNumber chan int
	matchGame          *GameMatch
	RoomSize           int

	ReadyRooms map[int64]*ReadyRoom
}

func NewGameHall() *GameHall {
	hall := &GameHall{}
	hall.ModuleInfo.New()
	hall.clients = make(map[string]*ClientPlayer)
	hall.ServerClientNumber = make(chan int)
	hall.matchGame = NewMatchGame(hall)
	hall.RoomSize, _ = strconv.Atoi(cfg.Get()["roomsize"])
	hall.ReadyRooms = make(map[int64]*ReadyRoom)
	return hall
}

func (this *GameHall) OnLoad() {
	this.AddCommandHandler(CMD_AddHallPlayer, this.Command_AddHallPlayer)
	this.AddCommandHandler(CMD_ClientLost, this.CMD_ClientLost)
	this.AddHandler(PBMessage.PBID_CS_GameHallTick, func(msg *Message) {})
	this.AddHandler(PBMessage.PBID_CS_MatchGame, this.matchGame.CS_MatchGame_Handler)
	this.AddHandler(PBMessage.PBID_CS_CancelMatch, this.matchGame.CS_CancelMatchGame_Halder)
	this.AddHandler(PBMessage.PBID_CS_SynRoomPlayerState, this.SynRoomPlayerState_Halder)
	go this.loop()
}

func (this *GameHall) loop() {
	ticker := time.Tick(time.Millisecond)
	for _ = range ticker {

		this.ModuleInfo.processMessage()

		this.matchGame.loop()

		for _, room := range this.ReadyRooms {
			room.Update()
		}

		this.hallTickTime += 1

		if this.hallTickTime >= HALLTICK_TIME {
			this.HallSecondTick()
			this.hallTickTime = 0
		}

	}
}

func (this *GameHall) AddPlayer(player *ClientPlayer) {
	this.clients[player.UserName] = player
}
func (this *GameHall) GetPlayer(userName string) *ClientPlayer {
	return this.clients[userName]
}
func (this *GameHall) RemovePlayer(player *ClientPlayer) {
	delete(this.clients, player.UserName)
}

func (this *GameHall) AddReadyRoom(room *ReadyRoom) {
	this.ReadyRooms[room.RoomID] = room
}
func (this *GameHall) GetReadyRoom(roomID int64) *ReadyRoom {
	return this.ReadyRooms[roomID]
}
func (this *GameHall) RemoveReadyRoom(roomID int64) {
	delete(this.ReadyRooms, roomID)
}

func (this *GameHall) GetServerNumber() chan int {
	GetNumMsg := CmdMessage(CMD_GetServerNumber, "setnum", this.ServerClientNumber)
	GetGameServer().AddMessage(GetNumMsg)
	return this.ServerClientNumber
}

func (this *GameHall) HallSecondTick() {
	tick := &PBMessage.SC_GameHallTick{}
	tick.OnLineNumber = proto.Int(<-this.GetServerNumber())
	for _, v := range this.clients {
		if v.PlayerState == PLAYERSTATE_Hall {
			v.Sess.SendPacket(PBMessage.PBID_SC_GameHallTick, tick)
		}
	}
}
func (this *GameHall) Command_AddHallPlayer(msg *Message) {
	player := msg.Param["Player"].(*ClientPlayer)
	player.PlayerState = PLAYERSTATE_Hall
	RetData := &PBMessage.SC_RetLogin{}
	RetData.RetType = proto.Int(0)
	RetData.UserName = proto.String(player.UserName)
	RetData.UserID = proto.Int64(player.UserID)
	RetData.ServerNews = proto.String("New Server New News -.-")
	RetData.OnLineNumber = proto.Int(<-this.GetServerNumber())
	msg.Sess.SendPacket(PBMessage.PBID_SC_RetLogin, RetData)

	this.AddPlayer(player)
	log.Info(player.UserName, " 进入大厅")
}

//大厅掉线处理
func (this *GameHall) CMD_ClientLost(msg *Message) {
	sess := msg.Param["Sess"].(*Session)
	clientPlayer := sess.UserData.(*ClientPlayer)
	log.Info("大厅移除玩家：", clientPlayer.UserName)
	this.RemovePlayer(clientPlayer)

	switch clientPlayer.PlayerState {
	case PLAYERSTATE_MATCHGAME:
		this.matchGame.Remove(clientPlayer)
	case PLAYERSTATE_ReadyRoom:
		readyRoom := this.GetReadyRoom(clientPlayer.ReadyRoomID)
		readyRoom.Destory()
	}
}
